﻿
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using wt.wine.Application.Common.Interfaces;
using wt.wine.Application.Common.Models;
using wt.wine.Application.ManageOrderTable;
using wt.wine.Domain.Entities;

namespace wt.wine.Infrastructure.Persistence.Repository
{
    public class ordertableRepository : IordertableRepository
    {
        private readonly IInternalHttpService _internalhttpservice;
        private readonly IApplicationDbContext _dbcontext;
        public ordertableRepository(IInternalHttpService internalhttpservice, IApplicationDbContext dbcontext)
        {
            _internalhttpservice = internalhttpservice;
            _dbcontext = dbcontext;
        }
        public async Task SendWine(string device, int num, CancellationToken cancellationtoken)
        {

            var model = await _internalhttpservice.PostJsonAsync<WineReturnModel>(Domain.Enums.ApiServiceType.JiuJi, "api/App/GoOutOfWine", new
            {
                device = device,
                returnUrl = "",
                num = num,
                type = 0
            }, cancellationtoken);
        }

        public async Task<int> GetOrderCountByDeviceid(int deviceid, CancellationToken cancellationtoken)
        {
            return await _dbcontext.ordertable.AsNoTracking().Where(p => p.deviceid == deviceid && p.state == 0).CountAsync(cancellationtoken);
        }

        public async Task<ordertable> getOrderTalbeByDeviceid(int deviceid, CancellationToken cancellationtoken)
        {
            return await _dbcontext.ordertable.AsNoTracking().Where(p => p.deviceid == deviceid && p.state == 0).FirstOrDefaultAsync(cancellationtoken);
        }

        public async Task EditOrderTableState(ordertable model, CancellationToken cancellationtoken)
        {
            _dbcontext.Entry<ordertable>(model).Property("state").IsModified = true;
            _dbcontext.Entry<ordertable>(model).Property("operationstate").IsModified = true;
            _dbcontext.Entry<ordertable>(model).Property("currentcapacity").IsModified = true;
            _dbcontext.Entry<ordertable>(model).Property("updatetime").IsModified = true;
            await _dbcontext.SaveChangesAsync(cancellationtoken);
        }

        /// <summary>
        /// 添加订单信息
        /// </summary>
        /// <param name="model"></param>
        /// <param name="cancellationtoken"></param>
        /// <returns></returns>
        public async Task AddOrderInfo(ordertable model, CancellationToken cancellationtoken)
        {
            await _dbcontext.ordertable.AddAsync(model, cancellationtoken);
            await _dbcontext.SaveChangesAsync(cancellationtoken);
        }

        /// <summary>
        /// 获取订单今日销售量
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="dt_begin"></param>
        /// <param name="dt_end"></param>
        /// <param name="cancellationtoken"></param>
        /// <returns></returns>
        public async Task<GetOrderstatisticsByDaysDTO> GetOrderStatisticsByDays(int userid, DateTime dt_begin, DateTime dt_end, CancellationToken cancellationtoken)
        {
            var list = await _dbcontext.ordertable.AsNoTracking().Where(p => p.state >= 0 && p.userid == userid && p.createtime >= dt_begin && p.createtime <= dt_end).ToListAsync(cancellationtoken);

            var model = new GetOrderstatisticsByDaysDTO(0, 0, 0, 0);
            if (list != null && list.Any())
            {
                model.Ordercount = list.Count();
                model.OutWineCount = list.Where(p => p.state == 1).Sum(p => p.ordercapacity);
                model.OrderPrice = list.Where(p => p.state == 1 || p.state == 0).Sum(p => p.price);

            }
            return model;
        }

        public async Task<ordertable> getOrderTalbeStateByDeviceid(int deviceid, int userid, CancellationToken cancellationtoken)
        {
            return await _dbcontext.ordertable.AsNoTracking().Where(p => p.deviceid == deviceid && p.userid == userid && p.state >= 0).OrderByDescending(p => p.id).FirstOrDefaultAsync(cancellationtoken);
        }

        /// <summary>
        /// 超过15分钟未处理设置为异常订单
        /// </summary>
        /// <param name="dt_time"></param>
        /// <param name="cancellationtoken"></param>
        /// <returns></returns>
        public async Task EditOrderStateByTime(DateTime dt_time, CancellationToken cancellationtoken)
        {
            var list = await _dbcontext.ordertable.AsNoTracking().Where(p => p.state == 0 && p.updatetime < dt_time).ToListAsync(cancellationtoken);
            if (list != null && list.Count() > 0)
            {
                for (int i = 0; i < list.Count(); i++)
                {
                    list[i].state = 3;
                    list[i].updatetime = DateTime.Now;
                    _dbcontext.Entry<ordertable>(list[i]).Property("state").IsModified = true;
                    _dbcontext.Entry<ordertable>(list[i]).Property("updatetime").IsModified = true;
                }
                await _dbcontext.SaveChangesAsync(cancellationtoken);
            }
        }

        public async Task<GetOrderTableListDTO> GetOrderTableListByUserId(int userid, int roletype, int deviceid, DateTime dt_begin, DateTime dt_end, int pageIndex, int pageSize, CancellationToken cancellationtoken)
        {
            int count = 0;
            int CapacityCount = 0;
            List<GetOrderTableModelDTO> list = new List<GetOrderTableModelDTO>() { };
            if (roletype == 2)
            {
                var query = from o in _dbcontext.ordertable.AsNoTracking().Where(p => p.createtime >= dt_begin && p.createtime <= dt_end && p.state >= 0 && (deviceid == 0 || (deviceid > 0 && p.deviceid == deviceid)))
                            from d in _dbcontext.devicetable.AsNoTracking().Where(p => p.id == o.deviceid).DefaultIfEmpty()
                            where d.id > 0
                            select new GetOrderTableModelDTO()
                            {
                                id = o.id,
                                currentcapacity = o.currentcapacity,
                                cusdeviceid = o.cusdeviceid,
                                membername = "",
                                name = o.name,
                                ordercapacity = o.ordercapacity,
                                orderno = "",
                                price = o.price,
                                state = o.state,
                                Createtime = o.createtime.ToString("yyyy-MM-dd HH:mm:ss")

                            };
                count = await query.CountAsync(cancellationtoken);
                CapacityCount = await query.Where(p => p.state == 1).Select(p => p.currentcapacity).SumAsync(cancellationtoken);
                list = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(cancellationtoken);
            }
            else if (roletype == 3)
            {
                var query = from o in _dbcontext.ordertable.AsNoTracking().Where(p => p.userid == userid && p.createtime >= dt_begin && p.createtime <= dt_end && p.state >= 0 && (deviceid == 0 || (deviceid > 0 && p.deviceid == deviceid)))
                            orderby o.createtime descending
                            select new GetOrderTableModelDTO()
                            {
                                id = o.id,
                                currentcapacity = o.state == 1 ? o.currentcapacity : 0,
                                cusdeviceid = o.cusdeviceid,
                                membername = "",
                                name = o.name,
                                ordercapacity = o.ordercapacity,
                                orderno = "",
                                price = o.price,
                                state = o.state,
                                Createtime = o.createtime.ToString("yyyy-MM-dd HH:mm:ss")
                            };
                count = await query.CountAsync(cancellationtoken);
                CapacityCount = await query.Where(p => p.state == 1).Select(p => p.currentcapacity).SumAsync(cancellationtoken);
                list = await query.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(cancellationtoken);
            }
            GetOrderTableListDTO model = new GetOrderTableListDTO(list, count, CapacityCount, pageIndex, pageSize);
            return model;
        }
    }
}
